package com.gsbelarus.gedemin.income.fragment;

import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.gsbelarus.gedemin.income.SumFormatter;
import com.gsbelarus.gedemin.income.sync.DataBaseHelper;
import com.gsbelarus.gedemin.income.table.ClientsTable;
import com.gsbelarus.gedemin.income.R;
import com.gsbelarus.gedemin.lib.ui.fragment.FragmentModel;
import com.jjoe64.graphview.BarGraphView;
import com.jjoe64.graphview.CustomLabelFormatter;
import com.jjoe64.graphview.GraphView.*;
import com.jjoe64.graphview.GraphViewSeries;
import com.jjoe64.graphview.GraphViewSeries.*;
import com.jjoe64.graphview.GraphViewStyle.*;

import java.util.List;

/**
 * Графики
 * (Меню - Графики)
 * Сгруппированная столбчатая диаграмма.
 * По оси иксов время в месяцах.
 * Для каждого месяца выводится плановая сумма и фактическая.
 * ************************
 * данные аналогичны Меню - Календарь;
 * если год не выбран, то берется текущий;
 * если проводок по месяцу нет, то все равно выводится с нулевыми суммами
 * ************************
 * Не обновлять библиотеку!, т.к. в текущей версии внесены изменения добавляющие некоторый функционал:
 * 1. явный и автоматический поворот записей в столбцах (ValuesOnTop) и корректное их отображение на разных устройствах.
 * 2. фон для записей в столбцах (ValuesOnTop).
 * 3. поправлено отображение легенды для экранов с высоким разрешением.
 * 4. отображение серий рядом друг с другом.
 */
public class GraphFrgm extends FragmentModel {

    /**
     * данные, полученные из БД, для вывода в plot:
     * ClientsTable.id - месяц 1..12
     * ClientsTable.paidSum - оплаченная сумма за месяц
     * ClientsTable.planSum - плановая сумма за месяц
     */
    private List<ClientsTable> contacts;

    private View rootView;

    private GraphViewSeries paidSeries;
    private GraphViewSeries planSeries;

    private SumFormatter sumFormatter;

    private TextView headerText;

    private String[] monthValues = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"};

    /**
     * @return id View для отрисовки в фрагменте
     */
    @Override
    public int getViewId() {
        return R.layout.frame_bar_plot;
    }

    /**
     * Если нужно переопределяется в классе наследнике, возвращает id View заголовка
     */
    @Override
    public Integer getHeaderId() {
        return R.layout.header;
    }

    @Override
    public void onCreateViewFragment(View rootView) {
        super.onCreateViewFragment(rootView);
        this.rootView = rootView;

        sumFormatter = new SumFormatter(context, SumFormatter.Format.FORMAT_IN_MILLION);

        /** заполняем заголовок */
        headerText = (TextView) rootView.findViewById(R.id.date_name);
        headerText.setText(argumentsHelper.selectedYear + " г.");
    }

    private void createGraph(boolean isVisiblePlan) {
        BarGraphView graphView = new BarGraphView(context, "");

        /** добавление данных на график */
        graphView.addSeries(paidSeries);
        if (isVisiblePlan) {
            graphView.addSeries(planSeries);
            graphView.setShowLegend(true);
        }

        /** подписываем ось Х месяцами и выставляем количество подписей по оси У */
        graphView.setHorizontalLabels(monthValues);
        graphView.getGraphViewStyle().setVerticalLabelsAlign(Paint.Align.RIGHT);
        graphView.getGraphViewStyle().setNumVerticalLabels(10);

        /** если 0, то ничего не отображаем, если >0 отображаем в определенном формате */
        graphView.setCustomLabelFormatter(new CustomLabelFormatter() {
            @Override
            public String formatLabel(double value, boolean b) {
                if (value == 0)
                    return "";
                return sumFormatter.format((long) value);
            }
        });

        /** размер шрифта, на всем графике один размер */
        graphView.getGraphViewStyle().setTextSize(getResources().getDimension(R.dimen.graph_label));

        /** выбор цвета для текста */
        graphView.getGraphViewStyle().setGridColor(Color.GRAY);
        graphView.getGraphViewStyle().setHorizontalLabelsColor(Color.GRAY);
        graphView.getGraphViewStyle().setVerticalLabelsColor(Color.GRAY);
        graphView.setValuesOnTopColor(Color.BLACK);

        /** данная функция работает некорректно, вертикальная сетка отображается всегда (баг в библиотеке) */
        graphView.getGraphViewStyle().setGridStyle(GridStyle.VERTICAL);

        /** показываем значения над столбиками */
        graphView.setDrawValuesOnTop(true);

        /** поворачиваем значения над столбиками */
        graphView.setAutoRotateValuesOnTop(true, -90);

        /** добавляем View графика в контейнер */
        LinearLayout layout = (LinearLayout) rootView.findViewById(R.id.graph);
        layout.addView(graphView);
    }

    /**
     * Чтение данных из БД в новом потоке
     */
    @Override
    public void readDataBase() {
        DataBaseHelper dbh = DataBaseHelper.getInstance(context);
        contacts = dbh.getGraphList(argumentsHelper.selectedYear);
    }

    /**
     * Метод вызывается после чтения данных из БД или при смене ориентации экрана.
     * Может быть вызван до окончания выполнения потока для запроса данных из БД, поэтому следует проверять данные на null.
     * Служит для инициализации View данными
     *
     * @param rootView корневое View
     */
    @Override
    public void initView(View rootView) {
        if (contacts == null)
            return;
        /** готовим данные для отображения на графике */
        GraphViewData[] paidData = new GraphViewData[contacts.size()];
        GraphViewData[] planData = new GraphViewData[contacts.size()];
        int i = 0;
        boolean isVisiblePlan = false;

        for (ClientsTable c : contacts) {
            long paidSum = c.getPaidSum();
            long planSum = c.getPlanSum();

            if (planSum > 0)
                isVisiblePlan = true;
            paidData[i] = new GraphViewData(c.getId(), paidSum);
            planData[i] = new GraphViewData(c.getId(), planSum);

            i++;
        }
        GraphViewSeriesStyle paidSeriesStyle = new GraphViewSeriesStyle(context.getResources().getColor(R.color.graph_paid), 1);
        GraphViewSeriesStyle planSeriesStyle = new GraphViewSeriesStyle(context.getResources().getColor(R.color.graph_plan), 1);

        paidSeries = new GraphViewSeries(getString(R.string.graph_paid), paidSeriesStyle, paidData);
        planSeries = new GraphViewSeries(getString(R.string.graph_plan), planSeriesStyle, planData);

        /** добавляем текст формата суммы в заголовок */
        appendHeaderText();

        createGraph(isVisiblePlan);
    }

    private void appendHeaderText() {
        String formatText = sumFormatter.formatText();
        if (!formatText.isEmpty())
            headerText.append(" " + context.getString(R.string.sum_in_million));
    }
}